package com.greensam.pixelengine.event.listener;

import com.greensam.pixelengine.event.pixel.PixelEventBus;
import com.greensam.pixelengine.event.pixel.PixelEventType;
import com.greensam.pixelengine.event.wrapped.PictureEditEventParams;
import com.greensam.pixelengine.pojo.vo.user.response.LoginUserVo;
import com.greensam.pixelengine.websocket.constant.MessageCode;
import com.greensam.pixelengine.websocket.constant.PictureEditActionEnum;
import com.greensam.pixelengine.websocket.constant.WebSocketEventType;
import com.greensam.pixelengine.websocket.dto.WebSocketPushMessage;
import com.greensam.pixelengine.websocket.handle.PictureEditBroadcaster;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Objects;

/**
 * 图片编辑事件监听器
 *
 * @author Ma Chengrui
 * @since 2025/11/4 9:42
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class PictureEditEventListener {

    private final PixelEventBus pixelEventBus;

    private final PictureEditBroadcaster broadcaster;

    @PostConstruct
    public void init() {
        pixelEventBus.subscribeWrapped(PixelEventType.PICTURE_USER_CONNECT.getCode(), PictureEditEventParams.class, this::onUserConnect);
        pixelEventBus.subscribeWrapped(PixelEventType.PICTURE_USER_DISCONNECT.getCode(), PictureEditEventParams.class, this::onUserDisConnect);
        pixelEventBus.subscribeWrapped(PixelEventType.PICTURE_ENTER_EDIT.getCode(), PictureEditEventParams.class, this::onEnterEdit);
        pixelEventBus.subscribeWrapped(PixelEventType.PICTURE_EDIT_ACTION.getCode(), PictureEditEventParams.class, this::onEditAction);
        pixelEventBus.subscribeWrapped(PixelEventType.PICTURE_EXIT_EDIT.getCode(), PictureEditEventParams.class, this::onExitEdit);
    }

    private void onUserConnect(PictureEditEventParams params) {
        log.debug("onUserConnect: {}", params);
    }

    private void onUserDisConnect(PictureEditEventParams params) {
        log.debug("onUserDisConnect: {}", params);
    }

    private void onEnterEdit(PictureEditEventParams params) {
        log.debug("onEnter: {}", params);
        Long pictureId = params.getPictureId();
        LoginUserVo user = params.getUser();
        Map<String, Object> data = Map.of(
                "message", user.getName() + " 进入编辑图片",
                "user", user
        );
        WebSocketPushMessage<Map<String, Object>> message = new WebSocketPushMessage<>(WebSocketEventType.PICTURE_EXIT, MessageCode.ENTER_EDIT, data);
        broadcaster.broadcast(pictureId, message);

    }

    private void onEditAction(PictureEditEventParams params) {
        log.debug("onEditAction: {}", params);
        // 校验当前编辑者
        Long pictureId = params.getPictureId();
        broadcaster.getEditingUser(pictureId);
        if (broadcaster.getEditingUser(pictureId) == null) {
            log.error("当前用户不是图片编辑者");
            return;
        }
        PictureEditActionEnum action = params.getAction();
        LoginUserVo user = params.getUser();
        String desc = action != null ? action.getDesc() : "UNKNOWN";
        Map<String, Object> data = Map.of(
                "message", "%s 执行 %s 操作", user.getName(), desc,
                "user", user,
                "action", Objects.requireNonNull(action)
        );
        WebSocketPushMessage<Map<String, Object>> message = new WebSocketPushMessage<>(WebSocketEventType.PICTURE_EXIT, MessageCode.EDIT_ACTION, data);
        broadcaster.broadcast(pictureId, message);
    }

    private void onExitEdit(PictureEditEventParams params) {
        log.debug("onExitEdit: {}", params);
        Long pictureId = params.getPictureId();
        Map<String, Object> data = Map.of(
                "message", params.getUser().getName() + " 退出编辑图片",
                "user", params.getUser()
        );
        WebSocketPushMessage<Map<String, Object>> message = new WebSocketPushMessage<>(WebSocketEventType.PICTURE_EXIT, MessageCode.EXIT_EDIT, data);
        broadcaster.broadcast(pictureId, message);
    }

}
